package com.example.aitoedu.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.example.aitoedu.config.FaceRecognitionProperties;
import com.example.aitoedu.constant.MessageConstant;
import com.example.aitoedu.entity.StuSign;
import com.example.aitoedu.entity.Student;
import com.example.aitoedu.entity.TeaSign;
import com.example.aitoedu.entity.User;
import com.example.aitoedu.exception.NotFaceException;
import com.example.aitoedu.exception.UploadErrorException;
import com.example.aitoedu.mapper.StuSignMapper;
import com.example.aitoedu.mapper.StudentMapper;
import com.example.aitoedu.mapper.TeaSignMapper;
import com.example.aitoedu.mapper.UserMapper;
import com.example.aitoedu.service.StuSignService;
import com.example.aitoedu.service.StudentService;
import com.example.aitoedu.service.TeacherService;
import com.example.aitoedu.utils.AliOSSUtils;
import com.example.aitoedu.utils.Base64Util;
import com.example.aitoedu.vo.StuSignVO;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
* @author 曹正豪
* @description 针对表【stu_sign(学生收到签到信息)】的数据库操作Service实现
* @createDate 2024-12-29 13:30:48
*/
@Service
public class StuSignServiceImpl extends ServiceImpl<StuSignMapper, StuSign>
    implements StuSignService {

    @Autowired
    private AliOSSUtils aliOSSUtils;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private FaceRecognitionProperties faceRecognitionProperties;

    @Autowired
    private StuSignMapper stuSignMapper;

    @Autowired
    private TeaSignMapper teaSignMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public SaResult uploadPhoto(MultipartFile file) {
        Long sid = Long.valueOf(StpUtil.getLoginId().toString());
        AipFace client = new AipFace(faceRecognitionProperties.getAppId(), faceRecognitionProperties.getApiKey(),
                faceRecognitionProperties.getSecretKey());
        String Base64 = null;
        try {
            Base64 = Base64Util.multipartFileToBase64(file);
        } catch (IOException e) {
            throw new UploadErrorException(MessageConstant.UPLOAD_ERROR);
        }
        HashMap<String, String> options = new HashMap<String, String>();
        options.put("user_info", "user's info");
        options.put("quality_control", "NORMAL");
        options.put("liveness_control", "LOW");
        JSONObject res = client.addUser(Base64, "BASE64", "traning", String.valueOf(sid), options);
        String upload = "";
        System.out.println(res);
        try {
            if(res.getInt("error_code")==223105){
                client.updateUser(Base64, "BASE64", "traning", String.valueOf(sid), options);
                this.upload(sid, file);
            }
            if(res.getInt("error_code")==222202){
                return SaResult.error("图片不是人脸");
            }
            if (res.getInt("error_code") == 0){
                this.upload(sid, file);
            }
        } catch (IOException e) {
            throw new UploadErrorException(MessageConstant.UPLOAD_ERROR);
        }
        return SaResult.ok(MessageConstant.UPLOAD_SUCCESS);
    }
    private void upload(Long sid,MultipartFile file) throws IOException {
        redisTemplate.delete("student_pl:"+sid);
        String upload = aliOSSUtils.upload(file);
        QueryWrapper queryWrapper = new QueryWrapper<>().eq("id", sid);
        LocalDateTime now = LocalDateTime.now();
        Student student = Student.builder()
                .signPhoto(upload)
                .updateTime(now)
                .build();
        User user = new User();
        user.setUpdateTime(now);
        studentMapper.update(student,queryWrapper);
        userMapper.update(user, queryWrapper);
    }

    @Override
    public SaResult sign(MultipartFile file, Long signId) throws Exception {
        Long sid = Long.valueOf(StpUtil.getLoginId().toString());
        AipFace client = new AipFace(faceRecognitionProperties.getAppId(), faceRecognitionProperties.getApiKey(),
                faceRecognitionProperties.getSecretKey());
        String Base64_now = Base64Util.multipartFileToBase64(file);
        Student student = studentMapper.selectById(sid);
        String url = student.getSignPhoto();
        if (url == null) return SaResult.error("请先上传您的人脸图片");
        Double comparison = faceComparison(client, Base64_now, url);
        if (comparison > 85){
            TeaSign teaSign = teaSignMapper.selectById(signId);
            LocalDateTime end_time = teaSign.getEndTime();
            if (LocalDateTime.now().isAfter(end_time)){
                return SaResult.error("签到时间已过");
            }
            String upload = aliOSSUtils.upload(file);
            StuSign stuSign = new StuSign();
            stuSign.setSignTime(LocalDateTime.now());
            stuSign.setPicture(upload);
            stuSign.setIsSign(1);
            stuSignMapper.update(stuSign,new QueryWrapper<StuSign>().eq("sid",sid).eq("sign_id",signId));
            return SaResult.ok("签到成功");
        }else {
            return SaResult.error("签到失败");
        }
    }

    @Override
    public List<StuSignVO> mySign() {
        Long sid = Long.valueOf(StpUtil.getLoginId().toString());
        List<StuSignVO> stuSignVOList = stuSignMapper.mySign(sid);
        return stuSignVOList;
    }

    private static Double faceComparison(AipFace client, String Base64_now, String Base64) throws Exception {
        // 将图片的URL传递给百度API
        MatchRequest req2 = new MatchRequest(Base64,"URL");
        // 将前端传过来的图片传递给百度API
        MatchRequest req1 = new MatchRequest(Base64_now, "BASE64");
        // 讲MatchRequest信息存入list集合中
        ArrayList<MatchRequest> requests = new ArrayList<>();
        requests.add(req1);
        requests.add(req2);

        // 进行人脸比对 返回值是json串
        JSONObject match = client.match(requests);

        System.out.println(match);
        if((int)match.get("error_code") == 222202){
            throw new NotFaceException(MessageConstant.NOT_FACE);
        }
        // 返回两张照片的相似度
        return match.getJSONObject("result").getDouble("score");
    }
}




